#pragma once

#include <iostream>
#include <string>
#include <functional>

#include "InetAddr.hpp"

class Connection;
class Reactor;
using hander_t = std::function<void(Connection* conn)>;

#define ListenConnection 1
#define NormalConnection 2

class Connection
{
public:
    Connection(int sockfd):_sockfd(sockfd)
    {}

    void RegisterHandler(hander_t recver,hander_t sender,hander_t excepter)
    {
        _handler_recver = recver;
        _handler_sender = sender;
        _handler_excepter = excepter;
    }
    void SetEvents(uint32_t events)
    { 
        _events = events;
    }
    void Close()
    {
        if(_sockfd > 0)
        {
            ::close(_sockfd);
        }
    }
    uint32_t Events()
    {
        return _events;
    }

    void SetReactor(Reactor* R)
    {
        _R = R;
    }

    void SetConnectionType(int type)
    {
        _type = type;
    }

    int Type()
    {
        return _type;
    }
    void AddInbuff(const std::string& in)
    {
        _inbuffer += in;
    }
    void SetAddr(const InetAddr& addr)
    {
        _addr = addr;
    }
    std::string& Inbuffer()
    {
        return _inbuffer;
    }
    void AddOutBuff(const std::string& in)
    {
        _outbuffer += in;
    }
    std::string& Outbuffer()
    {
        return _outbuffer;
    }
    void DiscardOutbuffer(int n)
    {
        _outbuffer.erase(0,n);
    }

    ~Connection()
    {}

    int Sockfd()
    {
        return _sockfd;
    }
public:
    hander_t _handler_recver;
    hander_t _handler_sender;
    hander_t _handler_excepter;
    Reactor* _R;
    InetAddr _addr;
private:
    int _sockfd;
    uint32_t _events;
    std::string _inbuffer;
    std::string _outbuffer;
    int _type;
};